home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Communications / IBTip / Source / MyObject.m < prev    next >
Encoding:
Text File  |  1995-06-12  |  9.2 KB  |  404 lines

  1.  
  2. #import "MyObject.h"
  3. #import "Term.h"
  4. #import "Modem.h"
  5. #import "Fdset.h"
  6. #import "Escaper.h"
  7. #import "StringResponder.h"
  8.  
  9. void fdHandler(int fd, void *selfp)
  10. {
  11.     id self = selfp;
  12.     [self getLine];
  13. }
  14.  
  15. int normal_key(int c, id escaper)
  16. {
  17.   static escape='~';
  18.   static esc_flag=0;
  19.  
  20.   if (esc_flag==0) {
  21.     if (c==escape) {
  22.       esc_flag=1;
  23.       return(0);
  24.     }
  25.     else {
  26.       return(1);
  27.     }
  28.   }
  29.   else {  /* esc_flag == 1  ..handle escaped character.. */
  30.     esc_flag=0;
  31.     if (c==escape) {     /* send escape character if two in a row */
  32.       return(1);
  33.     }
  34.     [escaper doEscape:c];
  35.     return(0);
  36.   }
  37. }
  38.  
  39. @implementation MyObject
  40.  
  41. - init;
  42. {
  43. //    int seteuid(uid_t);
  44.   
  45.     [super init];
  46.     seteuid(getuid());
  47.     term = [Term new];
  48.     escaper = [Escaper newEscaperWithTerm:term andModem:modem];
  49.     fdset = [Fdset new];
  50.     if (term==nil || fdset==nil || escaper==nil)
  51.     NXRunAlertPanel(NULL, "Problem initialising", NULL, NULL, NULL);
  52.     /* change terminal to raw mode */
  53.     [[[term setRaw] unSetEcho] unSetCrmod];
  54.     sr = [StringResponder new];
  55.     [sr addString:"CONNECT!" returnValue:connected];
  56.     [sr addString:"CONNECT 1200" returnValue:connect1200];
  57.     [sr addString:"CONNECT 2400" returnValue:connect2400];
  58.     [sr addString:"CONNECT 9600" returnValue:connect9600];
  59.     [sr addString:"NO CARRIER!" returnValue:no_carrier];
  60.     [sr addString:"BUSY!" returnValue:busy];
  61.     [sr addString:"AT" returnValue:modem_command];
  62.     [sr addString:"at" returnValue:modem_command];
  63.     
  64. // put back in later?
  65. //    if (argc>1) {
  66. //    [escaper readScript:argv[1]];
  67. //    }
  68.  
  69.     return self;
  70. }
  71.  
  72. - free;
  73. {
  74.     if (fdHandlerInstalled) {
  75.     DPSRemoveFD(mfd);
  76.     if (mfd) close(mfd);
  77.     }
  78.     return [super free];
  79. }
  80.  
  81. //
  82. //    delegate methods
  83. //
  84.  
  85. - awakeFromNib;
  86. {
  87.     static NXDefaultsVector tipDefaults = {
  88.     {"DebugLevel", "0"},
  89.     {"Speed", "9600"},
  90.     {"Parity", "NONE"},
  91.     {"Dial", ""},
  92.     {"Init", ""},
  93.     {"Port", "2"},
  94.     {"Flow", "NO"},
  95.     {"Capture", ""},
  96.     {"SendProtocol", "Xmodem"},
  97.     {"ReceiveProtocol", "Xmodem"},
  98.     {NULL}
  99.     };
  100.     int    num;
  101.     char *string;
  102.     
  103.     NXRegisterDefaults("IBTip", tipDefaults);
  104.     sscanf(NXGetDefaultValue("IBTip", "DebugLevel"), "%d", &debug);
  105.     [self resetConfig:self];
  106.     
  107.     sscanf(NXGetDefaultValue("IBTip", "Speed"), "%d", &num);
  108.     if (strcmp(NXGetDefaultValue("IBTip", "Port"), "1") == 0)
  109.     if (strcmp(NXGetDefaultValue("IBTip", "Flow"), "YES") == 0)
  110.         string = "/dev/cufa";
  111.     else
  112.         string = "/dev/cua";
  113.     else
  114.     if (strcmp(NXGetDefaultValue("IBTip", "Flow"), "YES") == 0)
  115.         string = "/dev/cufb";
  116.     else
  117.         string = "/dev/cub";
  118.     modem = [Modem newPort:string speed:num];
  119.     if (modem) {
  120.     mfd = [modem getfd];
  121.     [fdset addfd:mfd];  // listen on the modem
  122.     
  123.     DPSAddFD(mfd, fdHandler, self, NX_RUNMODALTHRESHOLD);
  124.     fdHandlerInstalled = YES;
  125.     if (strcmp(NXGetDefaultValue("IBTip", "Init"), "") != 0) {
  126.         [modem writeOut:NXGetDefaultValue("IBTip", "Init")];
  127.         [modem writeOut:"\r"];
  128.     }
  129.     } else {
  130.     NXRunAlertPanel(NULL, "Unable to open port %s", NULL, NULL, NULL, string);
  131.     [[output window] orderOut:self];
  132.     }
  133.  
  134.     connectSound = [Sound findSoundFor:"Connected"];
  135.  
  136.     return self;
  137. }
  138.  
  139. - windowDidBecomeMain:sender;
  140. {
  141.     [input selectText:self];
  142.     return self;
  143. }
  144.  
  145. //
  146. //    action methods
  147. //
  148.  
  149. - captureFile:sender
  150. {
  151.     id    savePanel = [SavePanel new];
  152.     
  153.     if ([savePanel runModal] == NX_OKTAG) {
  154.     [captureFile setStringValue:[savePanel filename]];
  155.     [captureFileWell setStringValue:[savePanel filename]];
  156.     }
  157.     return self;
  158. }
  159.  
  160. - configure:sender
  161. {
  162.     char string[80];
  163.     
  164.     if ([flow state])
  165.     NXWriteDefault("IBTip", "Flow", "YES");
  166.     else
  167.     NXWriteDefault("IBTip", "Flow", "NO");
  168.     sprintf(string, "%d", [port selectedTag]);
  169.     if (NXGetDefaultValue("IBTip", "Port") != string)
  170.     NXWriteDefault("IBTip", "Port", string);
  171.     sprintf(string, "%d", [[[speedPopup target] itemList] selectedTag]);
  172.     if (strcmp(NXGetDefaultValue("IBTip", "Speed"), string) != 0)
  173.     NXWriteDefault("IBTip", "Speed", string);
  174.     if (NXGetDefaultValue("IBTip", "Dial") != [dialString stringValue])
  175.     NXWriteDefault("IBTip", "Dial", [dialString stringValue]);
  176.     if (NXGetDefaultValue("IBTip", "Init") != [initString stringValue])
  177.     NXWriteDefault("IBTip", "Init", [initString stringValue]);
  178.     if (NXGetDefaultValue("IBTip", "Capture") != [captureFile stringValue])
  179.     NXWriteDefault("IBTip", "Capture", [captureFile stringValue]);
  180.     return self;
  181. }
  182.  
  183. - dial:sender;
  184. {
  185.     char temp[200];
  186.     char dialPrefix[]="ATDT", dialPostfix[]="\r"; 
  187.     // constants for now; later local var's of modem
  188.     
  189.     sprintf(temp,"%s%s%s\n",dialPrefix, [dialString stringValue], dialPostfix);
  190.     [modem writeOut:temp];
  191.     dialing = TRUE;
  192.     return self;
  193. }
  194.  
  195. - hangup:sender
  196. {
  197.     [[term pushState] reset];
  198.     [modem hangup];
  199.     dialing = FALSE;
  200.     [term popState];
  201.     return self;
  202. }
  203.  
  204. - receiveFile:sender
  205. {
  206.     [[term pushState] reset];
  207.     [modem receive];
  208.     [term popState];
  209.     return self;
  210. }
  211.  
  212. - reset:sender
  213. {
  214.     [term reset];
  215.     return self;
  216. }
  217.  
  218. - resetConfig:sender
  219. {
  220. //    {"Parity", "NONE"},
  221. //    {"SendProtocol", "Xmodem"},
  222. //    {"ReceiveProtocol", "Xmodem"},
  223.     
  224.     int num;
  225.     
  226.     if (strcmp(NXGetDefaultValue("IBTip", "Flow"), "YES") == 0)
  227.     [flow setState:1];
  228.     else
  229.     [flow setState:0];
  230.     sscanf(NXGetDefaultValue("IBTip", "Port"), "%d", &num);
  231.     [port selectCellWithTag:num];
  232. //    sscanf(NXGetDefaultValue("IBTip", "Speed", "%d", &num);
  233. //    [[speedPopup target] selectCellWithTag:num];
  234.     [speedPopup setTitle:NXGetDefaultValue("IBTip", "Speed")];
  235.     [dialString setStringValue:NXGetDefaultValue("IBTip", "Dial")];
  236.     [initString setStringValue:NXGetDefaultValue("IBTip", "Init")];
  237.     [captureFile setStringValue:NXGetDefaultValue("IBTip", "Capture")];
  238.     [captureFileWell setStringValue:NXGetDefaultValue("IBTip", "Capture")];
  239.     return self;
  240. }
  241.  
  242. - runScript:sender;
  243. {
  244.     id openPanel = [OpenPanel new];
  245.     FILE *script;
  246.     char buf[MAXPATHLEN];
  247.  
  248.     if ([openPanel runModal] == NX_OKTAG) {
  249.     if ((script = fopen([openPanel filename], "r")) == NULL) {
  250.         NXRunAlertPanel(NULL, "Can't read script", NULL, NULL, NULL);
  251.         return self;
  252.     }
  253.     while (feof(script) == 0) {
  254.         fgets(buf, MAXPATHLEN, script);
  255.         buf[strlen(buf)-1] = '\r';
  256.         [modem writeOut:buf];
  257.         sleep(2);
  258.     }
  259.     fclose(script);
  260.     }
  261.     return self;
  262. }
  263.  
  264. - sendFile:sender
  265. {
  266.     id openPanel = [OpenPanel new];
  267.  
  268.     if ([openPanel runModal] == NX_OKTAG) {
  269.     [[term pushState] reset];
  270.     [modem sendFile:[openPanel filename]];
  271.     [term popState];
  272.     }
  273.     return self;
  274. }
  275.  
  276. - sendLine:sender;
  277. {
  278.     if(normal_key([input stringValue][0],escaper)) {
  279.     [modem writeOut:[input stringValue]];
  280.     [modem writeOut:"\r"];
  281.     }
  282.     [input setStringValue:""];
  283.     [input selectText:self];
  284.     return self;
  285. }
  286.  
  287. /* check for zmodem invitation to download -- the ZRQINIT frame --
  288.  * else write characters to screen.
  289.  */
  290.  
  291. #define ZDLE 030
  292.  
  293. - getLine;
  294. {
  295.     char buf[16384];
  296.     int nfound;
  297.     static char ZRQINITseq[] =  "~B0";  // the first char will be ZDLE
  298. //    static char cr='\r';
  299.     int i, chars;
  300.     char ch;
  301.     enum responses seen;
  302.  
  303.     nfound = [fdset waitOnInputFor:0];
  304.     if (nfound < 0) {
  305.     [term reset];
  306.     perror("Fdset:waitOnInputFor had an error\n");
  307.     NXRunAlertPanel(NULL, "Fdset:waitOnInputFor had an error", NULL, NULL, NULL);
  308.     DPSRemoveFD(mfd);    /* end of file */
  309.     [NXApp terminate:self];
  310.     }
  311.     while (nfound--) {
  312.     if ([fdset getReadyfd] == mfd) {
  313.         if (!trigger) { // initialize trigger
  314.         trigger = [StringResponder new];
  315.         ZRQINITseq[0] = ZDLE;
  316.         [trigger addString:ZRQINITseq returnValue:1];
  317.         }
  318.     
  319.         chars = [modem readInto:buf];
  320.         if ([trigger inputString:buf]) {
  321.         [modem receiveZmodem];
  322.         } else {
  323.         for (i=0;i<chars;i++) {
  324.             ch = buf[i] &= 0x7f; //mask any parity bit
  325.         //    if (ch == '\n')
  326.         //      write(1,&cr,1);
  327.         }
  328.         }
  329.     }
  330.     }
  331.     
  332.     if (dialing) {
  333.     for (i=0; i < strlen(buf); i++) {  // convert end of line chars to !
  334.         if (buf[i] == '\r' || buf[i] == '\n') buf[i]='!';
  335.     }
  336.     seen = [sr inputString:buf];
  337.     dialing = FALSE;
  338.     switch (seen) {
  339.     case connected:
  340.         [connectSound play];
  341.         break;
  342.     case connect1200:
  343.         [modem setSpeed:1200];
  344.         [connectSound play];
  345.         break;
  346.     case connect2400:
  347.         [modem setSpeed:2400];
  348.         [connectSound play];
  349.         break;
  350.     case connect9600:
  351.         [modem setSpeed:9600];
  352.         [connectSound play];
  353.         break;
  354.     case no_carrier:
  355.         [self output:"modem detected no carrier, trying again...\n"];
  356.         [self dial:self];
  357.         break;
  358.     case busy:
  359.         [self output:"busy, trying again...\n"];
  360.         sleep(10);
  361.         [self dial:self];
  362.         break;
  363.     case no_dialtone:
  364.         [self output:"modem couldn't get dialtone; check phone\n"];
  365.         break;
  366.     case user_abort:
  367.         [self output:"User aborted dialing\n"];
  368.         break;
  369.     case modem_command:
  370.         dialing = TRUE;    // still, check next line
  371.         break;
  372.     }
  373.     } else {
  374.     [self output:buf];
  375.     }
  376.     [input selectText:self];
  377.     return self;
  378. }
  379.  
  380. - toggleCapture:sender
  381. {
  382.     if ([modem isCapturing]) {
  383.     [captureMenu setTitle:"Capture"];
  384.     [modem endCapture];
  385.     } else {
  386.     [captureMenu setTitle:"End Capture"];
  387.     if (strcmp([captureFile stringValue], "") == 0)
  388.         [modem captureSessionInFile:"tip.record"];
  389.     else
  390.         [modem captureSessionInFile:[captureFile stringValue]];
  391.     }
  392.     return self;
  393. }
  394.  
  395. - output:(char *)string;
  396. {
  397.     [output setSel:[output textLength] :0];
  398.     [output replaceSel:string];
  399.     [output scrollSelToVisible];
  400.     return self;
  401. }
  402.  
  403. @end
  404.